package com.hy.frame.util

import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.Canvas
import android.graphics.PixelFormat
import android.graphics.drawable.BitmapDrawable
import android.graphics.drawable.Drawable
import java.io.*

/**
 * Bitmap与DrawAble与byte[]与InputStream之间的转换工具类
 * @author HeYan
 * @time 2015-9-23 下午2:10:19
 */
class BitmapUtil {

    // 将byte[]转换成InputStream
    fun Byte2InputStream(b: ByteArray): InputStream {
        val bais = ByteArrayInputStream(b)
        return bais
    }

    // 将InputStream转换成byte[]
    fun InputStream2Bytes(input: InputStream): ByteArray? {
        var str = ""
        val readByte = ByteArray(1024)
        try {
            while (input.read(readByte, 0, 1024) != -1) {
                str += String(readByte).trim { it <= ' ' }
            }
            return str.toByteArray()
        } catch (e: Exception) {
            e.printStackTrace()
        }

        return null
    }

    // 将Bitmap转换成InputStream JPG
    fun bitmap2InputStream(bm: Bitmap): InputStream {
        val baos = ByteArrayOutputStream()
        bm.compress(Bitmap.CompressFormat.JPEG, 100, baos)
        return ByteArrayInputStream(baos.toByteArray())
    }

    // 将Bitmap转换成InputStream PNG
    fun bitmap2InputStream(bm: Bitmap, quality: Int): InputStream {
        val baos = ByteArrayOutputStream()
        bm.compress(Bitmap.CompressFormat.PNG, quality, baos)
        return ByteArrayInputStream(baos.toByteArray())
    }

    // 将InputStream转换成Bitmap
    fun inputStream2Bitmap(input: InputStream): Bitmap {
        return BitmapFactory.decodeStream(input)
    }

    // Drawable转换成InputStream
    fun Drawable2InputStream(d: Drawable): InputStream {
        val bitmap = this.drawable2Bitmap(d)
        return this.bitmap2InputStream(bitmap)
    }

    // InputStream转换成Drawable
    fun inputStream2Drawable(input: InputStream): Drawable {
        val bitmap = this.inputStream2Bitmap(input)
        return this.bitmap2Drawable(bitmap)
    }

    // Drawable转换成byte[]
    fun drawable2Bytes(d: Drawable): ByteArray {
        val bitmap = this.drawable2Bitmap(d)
        return this.bitmap2Bytes(bitmap)
    }

    // byte[]转换成Drawable
    fun bytes2Drawable(b: ByteArray): Drawable {
        val bitmap = this.bytes2Bitmap(b)
        return this.bitmap2Drawable(bitmap!!)
    }

    // Bitmap转换成byte[]
    fun bitmap2Bytes(bm: Bitmap): ByteArray {
        val baos = ByteArrayOutputStream()
        bm.compress(Bitmap.CompressFormat.PNG, 100, baos)
        return baos.toByteArray()
    }

    // byte[]转换成Bitmap
    fun bytes2Bitmap(b: ByteArray): Bitmap? {
        if (b.size != 0) {
            return BitmapFactory.decodeByteArray(b, 0, b.size)
        }
        return null
    }

    // Drawable转换成Bitmap
    fun drawable2Bitmap(drawable: Drawable): Bitmap {
        val bitmap = Bitmap.createBitmap(
            drawable.intrinsicWidth, drawable.intrinsicHeight,
            if (drawable.opacity != PixelFormat.OPAQUE) Bitmap.Config.ARGB_8888 else Bitmap.Config.RGB_565
        )
        val canvas = Canvas(bitmap)
        drawable.setBounds(0, 0, drawable.intrinsicWidth, drawable.intrinsicHeight)
        drawable.draw(canvas)
        return bitmap
    }

    // Bitmap转换成Drawable
    fun bitmap2Drawable(bitmap: Bitmap): Drawable {
        val bd = BitmapDrawable(bitmap)
        return bd
    }

    /**
     * 常用压缩
     */
    fun compressImage(bmp: Bitmap): Bitmap? {
        val baos = ByteArrayOutputStream()
        bmp.compress(Bitmap.CompressFormat.JPEG, 100, baos)//质量压缩方法，这里100表示不压缩，把压缩后的数据存放到baos中
        var options = 100
        while (baos.toByteArray().size / 1024 > 100) {    //循环判断如果压缩后图片是否大于100kb,大于继续压缩
            baos.reset()//重置baos即清空baos
            bmp.compress(Bitmap.CompressFormat.JPEG, options, baos)//这里压缩options%，把压缩后的数据存放到baos中
            options -= 10//每次都减少10
        }
        val isBm = ByteArrayInputStream(baos.toByteArray())//把压缩后的数据baos存放到ByteArrayInputStream中
        return BitmapFactory.decodeStream(isBm, null, null)
    }


    fun compressBitmap(bmp: Bitmap, path: String, maxWidth: Int, maxHeight: Int): Boolean {
        var bitmap = bmp
        val newOpts = BitmapFactory.Options()
        //开始读入图片，此时把options.inJustDecodeBounds 设回true了
        newOpts.inJustDecodeBounds = false
        val w = newOpts.outWidth
        val h = newOpts.outHeight
        //缩放比。由于是固定比例缩放，只用高或者宽其中一个数据进行计算即可
        var be = 1//be=1表示不缩放
        if (w > h && w > maxWidth) {//如果宽度大的话根据宽度固定大小缩放
            be = newOpts.outWidth / maxWidth
        } else if (w < h && h > maxHeight) {//如果高度高的话根据宽度固定大小缩放
            be = newOpts.outHeight / maxHeight
        }
        if (be <= 0)
            be = 1
        newOpts.inSampleSize = be//设置缩放比例
        //重新读入图片，注意此时已经把options.inJustDecodeBounds 设回false了
        bitmap = BitmapFactory.decodeFile(path, newOpts)
        val f = File(path)
        try {
            if (!f.exists())
                f.createNewFile()
            val fOut = FileOutputStream(f)
            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fOut)
            fOut.flush()
            fOut.close()
            return true
        } catch (e: IOException) {
            e.printStackTrace()
        }

        return false
    }

    companion object {
        private var tools: BitmapUtil? = BitmapUtil()

        val instance: BitmapUtil
            get() {
                if (tools == null) {
                    tools = BitmapUtil()
                    return tools!!
                }
                return tools!!
            }
    }
}